package com.mall4j.cloud.coupon.service.impl;

import com.mall4j.cloud.api.coupon.bo.CouponBO;
import com.mall4j.cloud.api.coupon.bo.CouponUseContext;
import com.mall4j.cloud.api.coupon.bo.FullReduceCoupon;
import com.mall4j.cloud.api.coupon.bo.NoThresholdCoupon;
import com.mall4j.cloud.api.coupon.constant.CouponTypeEnum;
import com.mall4j.cloud.api.coupon.dto.CouponUseReq;
import com.mall4j.cloud.api.coupon.dto.CouponUseResultDto;
import com.mall4j.cloud.api.coupon.dto.UpdateCouponOrderReq;
import com.mall4j.cloud.api.coupon.vo.CouponUseVo;
import com.mall4j.cloud.api.user.feign.UserFeignClient;
import com.mall4j.cloud.api.user.vo.UserApiVO;
import com.mall4j.cloud.common.exception.Mall4cloudException;
import com.mall4j.cloud.common.response.ServerResponseEntity;
import com.mall4j.cloud.coupon.mapper.CouponConfigMapper;
import com.mall4j.cloud.coupon.mapper.UserCouponMapper;
import com.mall4j.cloud.coupon.model.CouponConfig;
import com.mall4j.cloud.coupon.model.UserCoupon;
import com.mall4j.cloud.coupon.service.UserCouponService;
import org.bouncycastle.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class UserCouponServiceImpl implements UserCouponService {

    private static final Logger logger = LoggerFactory.getLogger(UserCouponServiceImpl.class);

    private UserCouponMapper userCouponMapper;
    private CouponConfigMapper couponConfigMapper;
    private UserFeignClient userFeignClient;



    public UserCouponServiceImpl(UserCouponMapper userCouponMapper,CouponConfigMapper configMapper,UserFeignClient userFeignClient) {
        this.userCouponMapper = userCouponMapper;
        this.couponConfigMapper = configMapper;
        this.userFeignClient = userFeignClient;
    }
    @Override
    public List<CouponBO> getUserCouponBo(long userId) {
        List<UserCoupon> userCoupons = userCouponMapper.getUserCoupon(userId);
        return userCoupons.stream().map(userCoupon -> {
            CouponBO bo = null;
            if(userCoupon.getCouponType()==CouponTypeEnum.FULL_REDUCE.value()) {
                bo = new FullReduceCoupon(userCoupon.getMinPrice(), userCoupon.getValue());
            }
            else if(userCoupon.getCouponType()==CouponTypeEnum.NO_THRESHOLD.value()) {
                bo = new NoThresholdCoupon(userCoupon.getValue());
            }
            if (bo == null) {
                throw new Mall4cloudException(String.format("no coupon type %s found",userCoupon.getCouponType()));
            }
            bo.setCouponId(userCoupon.getId());
            bo.setCouponName(userCoupon.getName());
            return bo;
        }).collect(Collectors.toList());
    }

    @Override
    public List<UserCoupon> getUserCoupon(long userId) {
        return userCouponMapper.getUserCoupon(userId);
    }

    @Override
    public CouponUseResultDto useCoupon(long userId,CouponUseReq useReq) {
        List<CouponBO> myCoupon = getUserCouponBo(userId);
        myCoupon.forEach(m->{
            System.out.println(m.getCouponId());
        });
        myCoupon=myCoupon.stream().filter(coupon-> Arrays.contains(useReq.getCouponIdList(), coupon.getCouponId())).collect(Collectors.toList());
        List<CouponUseVo> useVoList = new ArrayList<>();
        CouponUseContext couponContext = new CouponUseContext();
        couponContext.setTotal(useReq.getTotal());
        logger.info("use coupon,context={}",couponContext);
        // 计算优惠的总价值
        int totalValue = 0;
        for(CouponBO bo:myCoupon) {
            logger.info("check coupon,coupon={}",bo);
            CouponUseVo useVo = new CouponUseVo();
            useVo.setCouponId(bo.getCouponId());
            long value;
            if(bo.canUse(couponContext)) {
                useVo.setCanUse(true);
                value=bo.applyDiscount(couponContext);
                useVo.setBeforePrice(couponContext.getTotal());
//                useVo.setAfterPrice(newPrice);
                useVo.setValue(value);
                totalValue+=value;
//                couponContext.setTotal(newPrice);
//                System.out.println("apply discount ,new price:"+newPrice);
            }
            else {
                System.out.println("skip coupon:"+bo);
                useVo.setCanUse(false);
            }
            useVoList.add(useVo);
        }
        CouponUseResultDto resultDto = new CouponUseResultDto();
        resultDto.setValue(totalValue);
        resultDto.setCouponUseVoList(useVoList);
        return resultDto;
    }

    @Override
    public int updateCouponToUse(long userId, UpdateCouponOrderReq useReq) {
        int successCount = 0;
        System.out.println("update coupon use , coupon size:"+useReq.getCouponUseList().size());
        for(CouponUseVo couponUseVo:useReq.getCouponUseList()) {

            UserCoupon userCoupon = userCouponMapper.findCoupon(couponUseVo.getCouponId(),userId);
            if(userCoupon ==null) {
                throw new Mall4cloudException(String.format("没有找到用户%s的优惠卷%s",userId,couponUseVo.getCouponId()));
            }
            successCount+=userCouponMapper.updateUserCouponToUse(userCoupon.getId(), useReq.getOrderId(),couponUseVo.getValue());
        }
        return successCount;
    }

    @Override
    public long getUserCouponValueByOrderId(String orderId) {
        return userCouponMapper.getCouponValue(orderId);
    }

    @Override
    public long allocateUserCoupon(int couponId, long userId, String channel) {

        // 查找coupon
        CouponConfig couponConfig = couponConfigMapper.selectById(couponId);
        if(couponConfig==null) {
            throw new Mall4cloudException(String.format("coupon not found：%s",couponId));
        }
        if(userCouponMapper.checkExistsByConfigIdAndUserId(userId,couponId)!=null) {
            throw new Mall4cloudException("领取失败，已领取该优惠卷");
        }
        System.out.println("query userid:"+userId);
        ServerResponseEntity<UserApiVO> userData = userFeignClient.getUserData(userId);
        if(!userData.isSuccess()) {
            throw new Mall4cloudException("用户不存在");
        }
        UserCoupon userCoupon = new UserCoupon();
        userCoupon.setCouponConfigId(couponId);
        userCoupon.setUserId(userId);
        userCoupon.setValue(couponConfig.getValue());
        userCoupon.setMinPrice(couponConfig.getMinPrice());
        userCoupon.setName(couponConfig.getName());
//        TODO 改成链接coupon_config表
        userCoupon.setCouponType(couponConfig.getCouponType());
        return userCouponMapper.save(userCoupon);
    }
}
